package cn.opencodes.framework.core.redis;

import java.util.Set;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.support.atomic.RedisAtomicLong;

import cn.opencodes.framework.tools.utils.StringUtils;

/**
 * Redis工具类
 * 该解决方案必须多台服务器时间必须同步，否则覆盖上个客户端枷锁有效期，造成删除上个客户端锁
 * @author HJ
 */
public class RedisUtils {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    @Autowired
    private ValueOperations<String, Object> valueOperations;
    
    /**  默认过期时长，单位：秒 */
    public final static long DEFAULT_EXPIRE = 60 * 60 * 24;
    
    /**  不设置过期时长 */
    public final static long NOT_EXPIRE = -1;

    
    
    public void set(String key, Object value, long expire){
        valueOperations.set(key, value);
        if(expire != NOT_EXPIRE){
            redisTemplate.expire(key, expire, TimeUnit.SECONDS);
        }
    }

    public void set(String key, Object value){
        set(key, value, DEFAULT_EXPIRE);
    }

    @SuppressWarnings("unchecked")
	public <T> T get(String key, Class<T> clazz, long expire) {
        Object value = valueOperations.get(key);
        if (value != null) {
        	if(expire != NOT_EXPIRE){
        		redisTemplate.expire(key, expire, TimeUnit.SECONDS);
        	}
        	return (T)value;
		}
        return null;
    }

    public <T> T get(String key, Class<T> clazz) {
        return get(key, clazz, NOT_EXPIRE);
    }

    public void delete(String key) {
        redisTemplate.delete(key);
    }
    
	
	/**
	 * 实现命令：KEYS pattern，查找所有符合给定模式 pattern的 key
	 * @param pattern 不能为空
	 * @return keys
	 */
	public Set<String> keys(String pattern) {
		if (StringUtils.isNotBlank(pattern)) {
			return redisTemplate.keys(pattern);
		}
		return null;
	}
	
	/**
    * 自增长
    * @param key
    * @param liveTime 有效时间（秒）
    */
   public RedisAtomicLong getAtomicLong(String key, long liveTime) {
       RedisAtomicLong entityIdCounter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
       Long increment = entityIdCounter.get();

       if ((null == increment || increment.longValue() == 1) && liveTime > 0) {
    	   //初始设置过期时间
           entityIdCounter.expire(liveTime, TimeUnit.SECONDS);
       }

       return entityIdCounter;
   }
   
   /**
    * 自增长
    * @param key
    */
   public RedisAtomicLong getAtomicLong(String key) {
       return getAtomicLong(key, 0);
   }

}
